//
// Copyright (c) 2009 All Right Reserved
//
// vl
//
// 2009-01-01
// Contains ...
using System;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
namespace LargoCommon.Music
{
/// Harmonic relation.
/// Harmonic relation represents one harmonic connection and keeps
/// its characteristics (continuity, impulse,..). It is used for optimization
/// of harmonic stream in given time point.
[Serializable]
[XmlRoot]
public sealed class HarmonicRelation : HarmonicTransfer {
#region Fields
///
/// Structure A.
///
[NonSerialized]
private BinarySchema structA;
///
/// Structure B.
///
[NonSerialized]
private BinarySchema structB;
#endregion
#region Constructors
/// Initializes a new instance of the HarmonicRelation class. Serializable.
public HarmonicRelation() {
}
/// Initializes a new instance of the HarmonicRelation class.
/// Harmonic system.
/// First harmonic structure.
/// Second harmonic structure.
public HarmonicRelation(
HarmonicSystem harmonicSystem,
BinarySchema structureA,
BinarySchema structureB)
: base(harmonicSystem) {
Contract.Requires(harmonicSystem != null);
Contract.Requires(structureA != null);
Contract.Requires(structureB != null);
this.StructA = structureA;
this.StructB = structureB;
this.AddAllIntervals();
this.SetFormalProperties();
}
///
/// Initializes a new instance of the HarmonicRelation class.
///
/// The given system.
public HarmonicRelation(HarmonicSystem givenSystem)
: base(givenSystem) {
Contract.Requires(givenSystem != null);
}
#endregion
#region Properties
/// Gets or sets the first harmonic structure.
/// Property description.
public BinarySchema StructA {
get {
Contract.Ensures(Contract.Result() != null);
if (this.structA == null) {
throw new InvalidOperationException("Structure is null.");
}
return this.structA;
}
set => this.structA = value;
}
/// Gets or sets the second harmonic structure.
/// Property description.
public BinarySchema StructB {
get {
Contract.Ensures(Contract.Result() != null);
if (this.structB == null) {
throw new InvalidOperationException("Structure is null.");
}
return this.structB;
}
set => this.structB = value;
}
#endregion
#region Static methods
/// Compute total value of given characteristic.
/// General musical property.
/// First harmonic structure.
/// Second harmonic structure.
/// Positive values.
/// Returns value.
public static float RelationalCharacteristic(
GenProperty property,
BinarySchema structureA,
BinarySchema structureB,
bool positive) {
Contract.Requires(structureA != null);
Contract.Requires(structureB != null);
var harmonicSystem = (HarmonicSystem)structureA.GSystem;
var harRelation = new HarmonicRelation(harmonicSystem, structureA, structureB);
var value = harRelation.MeanValueOfProperty(property, positive, false);
return value;
}
#endregion
#region Public methods
/// Fills the given array with formal intervals to given element.
/// Element of system.
public void AddIntervalsLeadingToElement(byte element)
{
var places = this.StructA.Places;
foreach (var interval in
places.Select(e => new MusicalInterval(this.HarmonicSystem, e, element)))
{
this.Intervals.Add(interval);
}
}
#endregion
#region String representation
/// String representation of the object.
/// Returns value.
public override string ToString() {
var s = new StringBuilder();
s.AppendFormat("{0}->{1};", this.StructA, this.StructB);
//// s.Append(this.continuity); s.Append(this.impulse);
return s.ToString();
}
#endregion
#region Private methods
/// Makes array of intervals between tones of the cluster.
private void AddAllIntervals() {
var places = this.StructB.Places;
foreach (var elem in places) {
this.AddIntervalsLeadingToElement(elem);
}
}
#endregion
}
}